﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace server.app
{
    public sealed class UnitManager
    {
        World _world = null;

        public UnitManager(World world)
        {
            _world = world;
        }

        public Dictionary<string, long> NewNVValue(string dUnitId, uint level, string planKey = comm.objst.DPlan.DEFAULT_KEY)
        {
            var nvvalueDic = new Dictionary<string, long>();
            var nvalueDic = _world.DefineFile.GetAllNValue(comm.objst.NValueGroup.UNIT, true);
            var dUnit = _world.DefineFile.GetUnit(dUnitId);
            var plan = dUnit.GetPlan(planKey);
            foreach (var key in nvalueDic.Keys)
            {
                var nv = nvalueDic[key];
                nvvalueDic.Add(key, nv.Value);
                if (plan.DefNVValueDic.ContainsKey(key))
                {
                    nvvalueDic[key] = comm.objst.NValue.Parse(nv.Type, plan.DefNVValueDic[key]);
                }
            }

            nvvalueDic.TrySet(Const.NVALUE_UNIT_LEVEL, level);
            return nvvalueDic;
        }
        public void SetLevel(Object obj, uint level)
        {
            obj.NValueManager.TrySetNVValue(Const.NVALUE_UNIT_LEVEL, level);
        }
        public int GetSpeed(Object obj)
        {
            return (int)obj.NValueManager.GetNVValue(Const.NVALUE_UNIT_SPEED);
        }

        public bool CreateUnit(string playerId, comm.objst.CreateUnit createUnit, string planKey = comm.objst.DPlan.DEFAULT_KEY)
        {
            return _world.DataManager.Call<bool>(sqlx =>
            {
                sqlx.BeginTxn();
                if (CreateUnit(sqlx, playerId, createUnit, planKey))
                {
                    sqlx.CommitTxn();
                    return true;
                }
                return false;
            });
        }
        public bool CreateUnit(SQLx sqlx, string playerId, comm.objst.CreateUnit createUnit, string planKey = comm.objst.DPlan.DEFAULT_KEY)
        {
            var dUnit = _world.DefineFile.GetUnit(createUnit.UnitId);
            if (dUnit == null)
            {
                Console.WriteLine("dUnitId:" + createUnit.UnitId + " not found", comm.ConsoleColor.RED);
                return false;
            }
            var unit = new comm.objst.TableUnit
            {
                PlayerId = playerId,
                DObjectId = createUnit.UnitId,
                Name = dUnit.Name,
                NValueDic = NewNVValue(createUnit.UnitId, createUnit.Level, planKey)
            };

            #region DefEquipDic
            var equipTypes = comm.objst.DItem.ExpandAllEquipType(dUnit.CanEquipTypeList.ToArray());
            foreach (var equipType in equipTypes)
            {
                if (dUnit.DefEquipDic.ContainsKey(equipType) && dUnit.DefEquipDic[equipType] != "")
                {
                    var itemIds = _world.ItemManager.CreateItem(sqlx, playerId, new comm.objst.CreateItem
                    {
                        ItemId = dUnit.DefEquipDic[equipType],
                        Count = 1
                    });
                    if (itemIds != null)
                    {
                        unit.EquipDic.Add(equipType, itemIds[0]);
                    }
                }
            }
            #endregion

            for (int i = 0; i < createUnit.Count; i++)
            {
                unit.UnitId = createUnit.UnitId + "_" + comm.GUID.NewString();
                if (!_world.DataManager.TableUnit.CreateUnit(sqlx, unit))
                {
                    return false;
                }
            }
            return true;
        }

        public int GetAllUnitCount(string playerId)
        {
            return _world.DataManager.TableUnit.GetAllUnitCount(playerId);
        }

        public comm.objst.TableUnit GetUnit(string unitId)
        {
            return _world.DataManager.TableUnit.GetUnit(unitId);
        }
        public comm.objst.TableUnit[] GetAllUnit(string playerId)
        {
            return _world.DataManager.TableUnit.GetAllUnit(playerId);
        }
        public comm.objst.TableUnit[] GetAllUnit(string[] unitIds)
        {
            return _world.DataManager.TableUnit.GetAllUnit(unitIds);
        }
        public Dictionary<string, comm.objst.TableUnit> GetAllUnitDic(string[] unitIds)
        {
            var all = GetAllUnit(unitIds);
            var dic = new Dictionary<string, comm.objst.TableUnit>();
            foreach (var item in all)
            {
                dic.Add(item.UnitId, item);
            }
            return dic;
        }

        public comm.objst.UnitInfo[] GetAllUnitInfo(string playerId)
        {
            var list = new List<comm.objst.UnitInfo>();
            var all = _world.UnitManager.GetAllUnit(playerId);
            foreach (var item in all)
            {
                list.Add(new comm.objst.UnitInfo(item));
            }
            return list.ToArray();
        }
        public comm.objst.EquipInfo[] GetUnitAllEquipInfo(string unitId)
        {
            var list = new List<comm.objst.EquipInfo>();
            var unit = GetUnit(unitId);
            var itemDic = _world.ItemManager.GetAllItemDic(unit.EquipDic.ToAllItemId());
            foreach (var equipType in unit.EquipDic.Keys)
            {
                var itemId = unit.EquipDic[equipType];
                list.Add(new comm.objst.EquipInfo
                {
                    EquipType = equipType,
                    Item = itemDic.ContainsKey(itemId) ? new comm.objst.ItemInfo(itemDic[itemId]) : null
                });
            }
            return list.ToArray();
        }
    }
}
